package com.example.demo.service.impl;

import cn.hutool.core.util.StrUtil;
import com.aliyun.tea.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.SysQuestionAnswer;
import com.example.demo.entity.SysSubject;
import com.example.demo.entity.SysTitleSubmitRecord;
import com.example.demo.entity.SysUser;
import com.example.demo.judge.entity.LanguageVO;
import com.example.demo.judge.entity.SubmissionVO;
import com.example.demo.judge.main.JudgeService;
import com.example.demo.mapper.SysSubjectMapper;
import com.example.demo.mapper.SysTitleSubmitRecordMapper;
import com.example.demo.mapper.SysUserMapper;
import com.example.demo.service.SysSubjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.utils.UserInfoUtil;
import com.example.demo.utils.enu.SubmissionEnum;
import com.example.demo.utils.enu.UserInfoEnu;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ld&zjw
 * @since 2024-01-28
 */
@Service
public class SysSubjectServiceImpl extends ServiceImpl<SysSubjectMapper, SysSubject> implements SysSubjectService {

    @Autowired
    JudgeService judgeService;
    @Resource
    SysSubjectMapper sysSubjectMapper;
    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    SysTitleSubmitRecordMapper sysTitleSubmitRecordMapper;

    @Override
    public SysSubject getById(Long id) {
        SysSubject sysSubject = sysSubjectMapper.selectById(id);
        return sysSubject;
    }

    @Override
    public SubmissionVO submit(SubmissionVO submissionVO) throws Exception {
        LambdaQueryWrapper<SysSubject> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysSubject::getQuestionId, submissionVO.getQid());
        SysSubject sysSubject = sysSubjectMapper.selectOne(lambdaQueryWrapper);
        SubmissionVO submissionRes = null;
        if (sysSubject == null) {
            throw new Exception("未找到题库题目");
        }
        Float mem = 0F;
        Float time = 0F;
        for (int i = 1; i <= 5; i++) {
            if (i == 1 && !StringUtils.isEmpty(sysSubject.getInput1()) && !StringUtils.isEmpty(sysSubject.getOutput1())) {
                submissionVO.setStdin(sysSubject.getInput1());
                submissionVO.setExpected_output(sysSubject.getOutput1());
            } else if (i == 2 && !StringUtils.isEmpty(sysSubject.getInput2()) && !StringUtils.isEmpty(sysSubject.getOutput2())) {
                submissionVO.setStdin(sysSubject.getInput2());
                submissionVO.setExpected_output(sysSubject.getOutput2());
            } else if (i == 3 && !StringUtils.isEmpty(sysSubject.getInput3()) && !StringUtils.isEmpty(sysSubject.getOutput3())) {
                submissionVO.setStdin(sysSubject.getInput3());
                submissionVO.setExpected_output(sysSubject.getOutput3());
            } else if (i == 4 && !StringUtils.isEmpty(sysSubject.getInput4()) && !StringUtils.isEmpty(sysSubject.getOutput4())) {
                submissionVO.setStdin(sysSubject.getInput4());
                submissionVO.setExpected_output(sysSubject.getOutput4());
            } else if (i == 5 && !StringUtils.isEmpty(sysSubject.getInput5()) && !StringUtils.isEmpty(sysSubject.getOutput5())) {
                submissionVO.setStdin(sysSubject.getInput5());
                submissionVO.setExpected_output(sysSubject.getOutput5());
            } else {
                continue;
            }
            if (!StringUtils.isEmpty(sysSubject.getQuestionTimeLimit()) || !sysSubject.getQuestionTimeLimit().equals("0")) {
                submissionVO.setCpu_time_limit(Float.valueOf(sysSubject.getQuestionTimeLimit()));
            }
            if (!StringUtils.isEmpty(sysSubject.getQuestionMemLimit()) || !sysSubject.getQuestionMemLimit().equals("0")) {
                submissionVO.setMemory_limit(Float.valueOf(sysSubject.getQuestionMemLimit()));
            }
            submissionRes = judgeService.judgeCode(submissionVO);
            if (submissionRes.getStatus().getId().toString().equals(SubmissionEnum.Accepted.getValue())) {
                time = submissionRes.getTime() > time ? submissionRes.getTime() : time;
                mem = submissionRes.getMemory() > mem ? submissionRes.getMemory() : mem;
            } else {
                time = 0F;
                mem = submissionRes.getMemory() > mem ? submissionRes.getMemory() : mem;
                break;
            }
        }

        SysTitleSubmitRecord record = new SysTitleSubmitRecord();
        SysUser sysUser = sysUserMapper.selectById(UserInfoUtil.get(UserInfoEnu.userId.getCode()));
        record.setSubmitId(sysUser.getId());
        record.setSourceCode(submissionVO.getSource_code());
        record.setLanguageId(String.valueOf(submissionVO.getLanguage_id()));
        record.setLen(String.valueOf(submissionVO.getSource_code().length()));
        record.setTitleId(submissionVO.getQid());
        record.setTitleResult(String.valueOf(submissionRes.getStatus().getId()));
        record.setMem(mem);
        record.setTime(time);
        record.setSubmitName(sysUser.getUsername());
        record.setSubmitNick(sysUser.getNickName());
        record.setTitleTime(new Date());
        sysTitleSubmitRecordMapper.insert(record);
        return submissionRes;
    }

    @Override
    public List<LanguageVO> getLanguages() {
        return judgeService.getLanguageList();
    }

    @Override
    public Page<SysSubject> findPage(Integer pageNum, Integer pageSize, Integer questionId, String questionName, String questionType) {

        LambdaQueryWrapper<SysSubject> wrapper = Wrappers.<SysSubject>lambdaQuery();
        if (questionId != null) {
            wrapper.eq(SysSubject::getQuestionId, questionId);
        }
        if (StrUtil.isNotBlank(questionName)) {
            wrapper.like(SysSubject::getQuestionName, questionName);
        }
        if (StrUtil.isNotBlank(questionType)) {
            wrapper.like(SysSubject::getQuestionType, questionType);
        }
        Page<SysSubject> newsPage = sysSubjectMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
        int passNum, submitNum;
        double result;
        for (int i = 0; i < newsPage.getRecords().size(); i++) {
            passNum = newsPage.getRecords().get(i).getQuestionAccept();
            submitNum = newsPage.getRecords().get(i).getQuestionSubmit();
            result = (double) passNum / submitNum * 100;
            DecimalFormat decimalFormat = new DecimalFormat("#0.00");
            newsPage.getRecords().get(i).setPassingRate(decimalFormat.format(result));
        }
        return newsPage;

    }

}
